import { Menu } from '@app/db/common/entity/Menu';
import { Injectable } from '@nestjs/common';
import { DbService } from 'apps/admin/src/db/db.service';
import { FindOptionsSelect, FindOptionsWhere, In } from 'typeorm';
import CreateDto from './dto/create.dto';
import UpdateDto from './dto/update.dto';
import { MemberService } from '../member/member.service';

@Injectable()
export class MenuService {
    constructor(
        private readonly db:DbService,
        private readonly memberService:MemberService
    ){}

    async add(dto:CreateDto) {
        if(true == await this.db.menu.isExistsByWhere({name : dto.name, parentId : dto.parentId})) throw new Error('已存在相同的名称')
        if((dto.type === 'FOLD' || dto.type === 'PAGE') && true == await this.db.menu.isExistsByWhere({path : dto.path, parentId : dto.parentId})) throw new Error('已存在相同的路径')
        
        if(dto.type === 'BUTTON') {
            delete dto.component
            delete dto.display
            delete dto.path
            delete dto.keepAlive
            delete dto.sort
        }


        return this.db.menu.insert(dto)
    }

    async update(dto:UpdateDto) {
        let fields = Object.keys(dto) as (keyof Menu)[]
        if(fields.length == 0) return true
        fields.push('parentId')


        const row = await this.db.menu.findOne({ id : dto.id }, fields)
        
        if(!row) return

        let updateData:{[key in keyof Menu]? : Menu[key]} = {}

        const parentId = row.parentId
        delete row.parentId

        for(let k in row) {
            if(k in dto) {
                if(row[k] != dto[k]) {
                    updateData[k] = dto[k]
                }
            }
            
        }

        if(Object.keys(updateData).length == 0) return true

        if(updateData.name && (true == await this.db.menu.isExistsByWhere({name : updateData.name, parentId : parentId}))) throw new Error('已存在相同的名称')

        if(updateData.path && (true == await this.db.menu.isExistsByWhere({path : updateData.path, parentId : parentId}))) throw new Error('已存在相同的路径')
        return this.db.menu.update({id : dto.id}, updateData)
    }

    async del(id:number) {
        if((await this.db.menu.isExistsByWhere({parentId : id}))) throw new Error('该菜单存在子菜单，不可删除')
        return this.db.menu.delete({id : id})
    }


    async availableMenu(memberId:number) {
        const menus = await this.memberService.permissionMenu(memberId, null)
        return menus.filter(v => v.enable)
    }

    async list(memberId:number) {
        const menus = await this.memberService.permissionMenu(memberId, null)
        return menus
    }

    
}
